import os
import json
import constants as const
from eventcenter import eventcenter as event
from mapload import CardData, MapData, MapType
from resource_path import resource_path
class DataCenter:
    _instance = None  # 用于存储单例实例
    def __new__(cls, *args, **kwargs):
        # 如果实例不存在，则创建一个新的实例
        if cls._instance is None:
            cls._instance = super(DataCenter, cls).__new__(cls)
            cls._instance._data = {}  # 初始化数据存储
            cls._instance._datachangeListeners = {}
            cls._instance.curmap = MapData()
            cls._instance.rules = cls._instance.load_custom_rule("rules.txt")
        return cls._instance

    def is_prefix(self, a, b):
        # 如果 a 的长度大于 b 的长度，直接返回 False
        if len(a) > len(b):
            return False
        
        # 比较 a 和 b 的前 len(a) 个字符
        return a == b[:len(a)]
    def set_data(self, key, value):
        """设置数据"""
        keys = key.split('.')  # 按照 '.' 分割键路径
        current_level = self._data

        # 遍历前 n-1 层
        for k in keys[:-1]:
            if k not in current_level:
                current_level[k] = {}  # 如果该层级不存在，则创建空字典
            elif not isinstance(current_level[k], dict):
                raise ValueError(f"Key '{k}' is not a dictionary")

            current_level = current_level[k]

        # 设置最后一层的值
        last_key = keys[-1]
        current_level[last_key] = value

        
        for _,v in enumerate(self._datachangeListeners):
            if self.is_prefix(v, key):
                self.notify_datachangeListeners(key, value, v)
            

    def get_data(self, key, default=None):
        """获取数据"""
        keys = key.split('.')
        current_level = self._data

        # 遍历所有层级
        for k in keys:
            if k not in current_level:
                if default is not None:
                    return default
                print(f"[DataCenter]: Key {k} not found")
                return None
            current_level = current_level[k]

        return current_level if current_level is not None else default

    def remove_data(self, key):
        if key in self._data:
            del self._data[key]

    def clear(self):
        self._data.clear()

    def __str__(self):
        return str(self._data)
    

    def add_datachangeListener(self, key, listener):
        if key not in self._datachangeListeners:
            self._datachangeListeners[key] = []
        self._datachangeListeners[key].append(listener)

    def remove_datachangeListener(self, key, listener):
        if key in self._datachangeListeners:
            self._datachangeListeners[key].remove(listener)

    def notify_datachangeListeners(self, key, value, realkey):
        if key in self._datachangeListeners:
            for listener in self._datachangeListeners[key]:
                listener(key, value, realkey)

    def clear_datachangeListeners(self):
        self._datachangeListeners.clear()

    def get_uid(self):
        return self.curmap.get_card_uid()

    def get_card(self, uid):
        return self.curmap.cards.get(uid)

    def set_card(self, v):
        self.curmap.set_card(v)

    def load_mapdata(self, filename):
        full_path = self.curmap.get_full_path(filename)
        # 检查文件是否存在
        if os.path.exists(full_path) and os.path.getsize(full_path) > 0:
            try:
                self.curmap.load_from_file(filename)
                return True
            except json.JSONDecodeError:
                print(f"[DataCenter]: Map file {full_path} is invalid, create new map data")
                self.curmap.set_data(filename, const.game_window_width, const.game_window_height)
                return True
        else:
            print(f"[DataCenter]: Map file {full_path} not found or empty, create new map data")
            self.curmap.set_data(filename, const.game_window_width, const.game_window_height)
            return True
    def save_mapdata(self, filename):
        return self.curmap.save_to_file(filename)

    
    def load_custom_rule(self, filename):
        # 使用resource_path获取conf目录的路径
        conf_dir = os.path.join(resource_path('res'), 'conf')
        # 确保目录存在
        if not os.path.exists(conf_dir):
            os.makedirs(conf_dir, exist_ok=True)
        
        full_path = os.path.join(conf_dir, filename)
        
        # 检查文件是否存在
        if not os.path.exists(full_path) or os.path.getsize(full_path) == 0:
            print(f"[DataCenter]: Rule file {full_path} not found or empty, creating with default rules")
            # 创建目录（如果不存在）
            os.makedirs(os.path.dirname(full_path), exist_ok=True)
            # 创建文件并写入默认规则
            try:
                with open(full_path, 'w', encoding='utf-8') as f:
                    f.write("fix f\nrandom r\n")
                print(f"[DataCenter]: Created default rule file at {full_path}")
            except Exception as e:
                print(f"[DataCenter]: Error creating rule file {full_path}: {e}")
                return {}
            
            # 返回默认规则
            rules = {"fix": "f", "random": "r"}
            return rules
        
        rules = {}
        try:
            with open(full_path, 'r', encoding='utf-8') as f:
                for line in f:
                    line = line.strip()
                    if not line or line.startswith('#'):
                        continue  # 跳过空行和注释行
                    
                    parts = line.split()
                    if len(parts) >= 1:
                        key = parts[0]
                        # 如果第二列为空，则value也为key
                        value = parts[1] if len(parts) > 1 else key
                        rules[key] = value
            
            return rules
        except Exception as e:
            print(f"[DataCenter]: Error loading rule file {full_path}: {e}")
            return {}

    def get_ruleBrief(self, key):
        if key in self.rules:
            return self.rules[key]
        else:
            return key
    
    def get_rules(self):
        return self.rules
    
    def get_rule_keys(self):
        """获取所有规则的键名列表"""
        return list(self.rules.keys())

datacenter = DataCenter()


# 使用例子
if __name__ == "__main__":
    # 创建 DataCenter 实例
    dc1 = DataCenter()
    dc2 = DataCenter()

    # 验证是否为单例
    print(f"dc1 和 dc2 是否为同一个实例: {dc1 is dc2}")  # 输出: True

    # 设置数据
    dc1.set_data("username", "Alice")
    dc1.set_data("age", 30)

    # 获取数据
    print(f"获取 username: {dc2.get_data('username')}")  # 输出: Alice
    print(f"获取 age: {dc2.get_data('age')}")           # 输出: 30

    # 移除数据
    dc2.remove_data("age")
    print(f"移除 age 后的数据: {dc1}")  # 输出: {'username': 'Alice'}

    # 清空数据
    dc1.clear()
    print(f"清空后数据: {dc2}")  # 输出: {}